<template>
  <div class="form-panel-container">
    <div class="formTitle" v-if="props.formTitle">{{ props.formTitle }}</div>
    <div class="header" v-if="props.isHasHeader">
      <!-- 配置右上角操作按钮 -->
      <slot name="headerSlot">
        <!-- 返回按钮 -->
        <!--        <v-button text="返回" @click="previous"></v-button>-->
      </slot>
    </div>
    <div class="content" ref="content">
      <el-form ref="formRef" :rules="rules" :model="form" label-width="100px">
        <!-- 配置表单控件 -->
        <slot></slot>
      </el-form>
    </div>
    <div class="footer" v-if="props.isFooterShow">
      <div class="footer-button">
        <v-button text="返回" @click="previous"></v-button>
        <!-- 在默认保存按钮左侧配置其他操作按钮 -->
        <slot name="saveBeforeSlot"></slot>

        <slot name="footerSlot">
          <!-- 保存按钮 -->
          <v-button
              :text="props.submitText"
              :disabled="submitDisabled"
              @click="validate"
              type="primary"
          ></v-button>
        </slot>
        <slot name="saveAfterSlot"></slot>
      </div>
    </div>
  </div>
</template>
<script lang="ts" setup>
import {reactive, toRefs, ref, nextTick, inject} from 'vue'
import {useRouter} from 'vue-router'
import type {FormInstance} from 'element-plus'
import request from '@/api'
import _ from 'lodash'

let $message: any = inject('$message')
const $router = useRouter()
const $emit = defineEmits(['update'])

interface FormPanelProps {
  isFooterShow?: boolean
  isHasHeader?: boolean
  form: { [key: string]: any }
  submitText?: string
  // 表单数据提交接口
  submitUrl: string
  queryMethod?: string
  // 表单数据查询接口的Content-Type
  queryContentType?: String
  // 表单数据查询接口的transformRequest
  queryTransformRequest?: Array<any>
  // 表单数据查询接口
  queryUrl: string,
  id?: string | number,
  // 表单数据提交前的回调函数，参数为当前表单数据，对此参数的操作不会影响原数据
  submitBefore?: Function,
  // 表单数据提交的成功回调，两个参数分别为接口返回的data和msg
  submitSuccess?: Function,
  //表单标题
  formTitle?: String
}

const formPanelData = reactive({
  submitDisabled: false,
  rules: {}
})

const formRef = ref<FormInstance>()

const props = withDefaults(defineProps<FormPanelProps>(), {
  isFooterShow: true,
  isHasHeader: true,
  submitText: '提交',
  queryMethod: 'get'
})

const previous = () => {
  $router.go(-1)
}

const validate = () => {
  formRef.value!.validate(valid => {
    console.log(props.form)
    if (!valid) {
      return;
    }
    let submitData = _.cloneDeep(props.form)
    const result = props.submitBefore ? props.submitBefore(submitData) : true
    if (!result) {
      return;
    }
    submitDisabled.value = true
    if (props.id) {
      //编辑
      request.put<any, OwnAxiosResponse<null>>(`${props.submitUrl}/${props.id}`, submitData).then(res => {
        if (res.status === 0) {
          $message.success('修改成功')
          $router.go(-1);
          // formRef.value!.resetFields()
        } else {
          $message.error(res.msg)
        }
      })
    } else {
      //新增
      request.post<any, OwnAxiosResponse<null>>(`${props.submitUrl}`, submitData).then(res => {
        if (res.status === 0) {
          $message.success('创建成功')
          $router.go(-1);
          // formRef.value!.resetFields()
        } else {
          $message.error(res.msg)
        }
      })
    }
    submitDisabled.value = false
  })
}
const {submitDisabled, rules} = toRefs(formPanelData)

const getData = (params: any) => {
  nextTick(() => {
    request.get(`${props.queryUrl}/${params.id}`).then(res => {
      if (res.status === 0) {
        const data = res.data
        $emit('update', data)
      }
    })
  })
}

// 重置表单数据
const resetForm = () => {
  formRef.value.resetFields()
}

const clearValidate = (props) => {
  formRef.value.clearValidate(props)
}
// 对部分表单字段进行校验的方法
const validateField = (props, callback) => {
  formRef.value.validateField(props, callback)
}


defineExpose
({
  getData,
  resetForm,
  clearValidate,
  validateField
})
</script>
<style scoped lang="scss">
.form-panel-container {
  display: flex;
  flex-direction: column;
  text-align: left;
  height: 100%;
  background-color: #fff;
  position: relative;
  //padding: 20px;

  .formTitle {
    font-size: 18px;
    line-height: 1.5;
    font-weight: 500;
    margin-bottom: 30px;
  }

  .header {
    position: absolute;
    top: 0px;
    right: 20px;
    z-index: 1;

    :not(:last-child) {
      margin-right: 8px;
    }
  }

  .content {
    overflow: auto;
    margin-bottom: 20px;
    height: calc(100% - 97px);

    :deep(.el-form) {
      display: flex;
      flex-wrap: wrap;
      justify-content: flex-start;
      align-items: flex-start;


      .el-form-item {
        width: 45%;
        // display: inline-flex;
        margin-bottom: 30px;
        @media screen and (max-width: 1400px) {
          width: 100%
        }

        &.no-flex {
          .el-form-item__content {
            display: block;
          }
        }
      }
    }
  }

  .footer {
    text-align: right;

    .footer-button {
      position: absolute;
      bottom: 0;
      right: 0;

      > :nth-child(n) {
        &:not(:last-child) {
          margin-right: 10px;
        }
      }
    }
  }
}
</style>
